package process_demo.thread_safe.phenomenon;

/**
 * synchronized 对象相同，都是Object，互斥
 * @author haomin
 * @date 2022/04/22 19:23
 **/
// 演示线程不安全的现象
public class Main5 {
    // 定义一个共享的数据 —— 静态属性的方式来体现
    static int r = 0;

    // 定义加减的次数
    // COUNT 越大，出错的概率越大；COUNT 越小，出错的概率越小
    static final int COUNT = 1_0000_0000;

    // 定义两个线程，分别对 r 进行 加法 + 减法操作
    static class Add extends Thread {
        private Object o;
        public Add(Object o) {
            this.o = o;
        }

        @Override
        public void run() {
            // 加锁方式1 方式1加锁“粒度”较粗
            synchronized(o) {
                for (int i = 0; i < COUNT; i++) {
                    r++;
                }
            }
        }
    }

    static class Sub extends Thread {
        private Object o;
        public Sub(Object o) {
            this.o = o;
        }

        @Override
        public void run() {
            synchronized(o) {
                for (int i = 0; i < COUNT; i++) {
                    r--;
                }
            }
        }
    }
    static class add1 extends Thread{
        @Override
        public void run() {
            System.out.println("ss");
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Object o = new Object();
        Add add = new Add(o);
        add.start();

        Sub sub = new Sub(o);
        sub.start();

        add.join();
        sub.join();

        // 理论上，r 被加了 COUNT 次，也被减了 COUNT 次
        // 所以，结果应该是 0
        System.out.println(r);
    }
}